package com.lifeverse.service;

import com.lifeverse.controller.LifeEntityWebSocketController;
import com.lifeverse.entity.LifeEntity;
import com.lifeverse.entity.enums.LifeEntityStatus;
import com.lifeverse.entity.enums.LifeEntityType;
import com.lifeverse.repository.LifeEntityRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import jakarta.persistence.criteria.Predicate;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 生命体服务类
 * 提供生命体的核心业务逻辑
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class LifeEntityService {

    private final LifeEntityRepository lifeEntityRepository;
    private final LifeEntityWebSocketController webSocketController;

    /**
     * 分页查询生命体列表
     */
    public Page<LifeEntity> findAll(String search, LifeEntityType type, LifeEntityStatus status, Pageable pageable) {
        Specification<LifeEntity> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            // 基础过滤条件：未删除
            predicates.add(criteriaBuilder.equal(root.get("deleted"), false));
            
            // 名称搜索
            if (StringUtils.hasText(search)) {
                predicates.add(criteriaBuilder.like(
                    criteriaBuilder.lower(root.get("name")), 
                    "%" + search.toLowerCase() + "%"
                ));
            }
            
            // 类型过滤
            if (type != null) {
                predicates.add(criteriaBuilder.equal(root.get("type"), type));
            }
            
            // 状态过滤
            if (status != null) {
                predicates.add(criteriaBuilder.equal(root.get("status"), status));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        return lifeEntityRepository.findAll(spec, pageable);
    }

    /**
     * 根据ID查找生命体
     */
    public Optional<LifeEntity> findById(Long id) {
        return lifeEntityRepository.findById(id)
            .filter(entity -> !entity.getDeleted());
    }

    /**
     * 根据名称查找生命体
     */
    public Optional<LifeEntity> findByName(String name) {
        return lifeEntityRepository.findByNameAndDeletedFalse(name);
    }

    /**
     * 创建生命体
     */
    @Transactional
    public LifeEntity create(LifeEntity lifeEntity) {
        log.info("Creating new life entity: {}", lifeEntity.getName());
        
        // 验证名称唯一性
        if (lifeEntityRepository.findByNameAndDeletedFalse(lifeEntity.getName()).isPresent()) {
            throw new IllegalArgumentException("生命体名称已存在: " + lifeEntity.getName());
        }
        
        // 设置默认值
        if (lifeEntity.getStatus() == null) {
            lifeEntity.setStatus(LifeEntityStatus.CREATING);
        }
        
        if (lifeEntity.getBirthTime() == null) {
            lifeEntity.setBirthTime(LocalDateTime.now());
        }
        
        if (lifeEntity.getLastActiveAt() == null) {
            lifeEntity.setLastActiveAt(LocalDateTime.now());
        }
        
        // 初始化分数
        if (lifeEntity.getEnergyLevel() == null) {
            lifeEntity.setEnergyLevel(BigDecimal.valueOf(100.00));
        }
        
        if (lifeEntity.getHealthScore() == null) {
            lifeEntity.setHealthScore(BigDecimal.valueOf(100.00));
        }
        
        if (lifeEntity.getWisdomScore() == null) {
            lifeEntity.setWisdomScore(BigDecimal.valueOf(0.00));
        }
        
        if (lifeEntity.getCreativityScore() == null) {
            lifeEntity.setCreativityScore(BigDecimal.valueOf(0.00));
        }
        
        if (lifeEntity.getCollaborationScore() == null) {
            lifeEntity.setCollaborationScore(BigDecimal.valueOf(50.00));
        }
        
        LifeEntity savedEntity = lifeEntityRepository.save(lifeEntity);
        
        // 创建完成后激活生命体
        savedEntity.setStatus(LifeEntityStatus.ACTIVE);
        savedEntity = lifeEntityRepository.save(savedEntity);
        
        // 广播创建事件
        webSocketController.broadcastEntityCreated(savedEntity);
        
        log.info("Life entity created successfully: {} (ID: {})", savedEntity.getName(), savedEntity.getId());
        return savedEntity;
    }

    /**
     * 更新生命体
     */
    @Transactional
    public LifeEntity update(Long id, LifeEntity updateData) {
        log.info("Updating life entity: {}", id);
        
        LifeEntity existingEntity = lifeEntityRepository.findById(id)
            .filter(entity -> !entity.getDeleted())
            .orElseThrow(() -> new IllegalArgumentException("生命体不存在: " + id));
        
        // 验证名称唯一性（排除自己）
        if (StringUtils.hasText(updateData.getName()) && 
            !updateData.getName().equals(existingEntity.getName())) {
            Optional<LifeEntity> duplicateEntity = lifeEntityRepository.findByNameAndDeletedFalse(updateData.getName());
            if (duplicateEntity.isPresent() && !duplicateEntity.get().getId().equals(id)) {
                throw new IllegalArgumentException("生命体名称已存在: " + updateData.getName());
            }
        }
        
        // 更新字段
        if (StringUtils.hasText(updateData.getName())) {
            existingEntity.setName(updateData.getName());
        }
        
        if (updateData.getType() != null) {
            existingEntity.setType(updateData.getType());
        }
        
        if (updateData.getStatus() != null) {
            existingEntity.setStatus(updateData.getStatus());
        }
        
        if (updateData.getDescription() != null) {
            existingEntity.setDescription(updateData.getDescription());
        }
        
        if (updateData.getConsciousnessLevel() != null) {
            existingEntity.setConsciousnessLevel(updateData.getConsciousnessLevel());
        }
        
        // 更新活跃时间
        existingEntity.updateLastActiveTime();
        
        LifeEntity savedEntity = lifeEntityRepository.save(existingEntity);
        
        // 广播更新事件
        webSocketController.broadcastEntityUpdated(savedEntity);
        
        log.info("Life entity updated successfully: {} (ID: {})", savedEntity.getName(), savedEntity.getId());
        
        return savedEntity;
    }

    /**
     * 删除生命体（软删除）
     */
    @Transactional
    public void delete(Long id) {
        log.info("Deleting life entity: {}", id);
        
        LifeEntity entity = lifeEntityRepository.findById(id)
            .filter(e -> !e.getDeleted())
            .orElseThrow(() -> new IllegalArgumentException("生命体不存在: " + id));
        
        String entityName = entity.getName();
        
        // 软删除
        entity.setDeleted(true);
        entity.setDeletedAt(LocalDateTime.now());
        entity.setStatus(LifeEntityStatus.TERMINATED);
        
        lifeEntityRepository.save(entity);
        
        // 广播删除事件
        webSocketController.broadcastEntityDeleted(entity.getId(), entityName);
        
        log.info("Life entity deleted successfully: {} (ID: {})", entityName, entity.getId());
    }

    /**
     * 激活生命体
     */
    @Transactional
    public LifeEntity activate(Long id) {
        log.info("Activating life entity: {}", id);
        
        LifeEntity entity = findById(id)
            .orElseThrow(() -> new IllegalArgumentException("生命体不存在: " + id));
        
        String oldStatus = entity.getStatus().name();
        entity.setStatus(LifeEntityStatus.ACTIVE);
        entity.updateLastActiveTime();
        
        LifeEntity savedEntity = lifeEntityRepository.save(entity);
        
        // 广播状态变更事件
        webSocketController.broadcastStatusChanged(savedEntity, oldStatus, LifeEntityStatus.ACTIVE.name());
        
        return savedEntity;
    }

    /**
     * 休眠生命体
     */
    @Transactional
    public LifeEntity dormant(Long id) {
        log.info("Setting life entity to dormant: {}", id);
        
        LifeEntity entity = findById(id)
            .orElseThrow(() -> new IllegalArgumentException("生命体不存在: " + id));
        
        String oldStatus = entity.getStatus().name();
        entity.setStatus(LifeEntityStatus.DORMANT);
        
        LifeEntity savedEntity = lifeEntityRepository.save(entity);
        
        // 广播状态变更事件
        webSocketController.broadcastStatusChanged(savedEntity, oldStatus, LifeEntityStatus.DORMANT.name());
        
        return savedEntity;
    }

    /**
     * 进化生命体
     */
    @Transactional
    public LifeEntity evolve(Long id) {
        log.info("Evolving life entity: {}", id);
        
        LifeEntity entity = findById(id)
            .orElseThrow(() -> new IllegalArgumentException("生命体不存在: " + id));
        
        String oldStatus = entity.getStatus().name();
        entity.setStatus(LifeEntityStatus.EVOLVING);
        entity.evolve();
        entity.updateLastActiveTime();
        
        // 进化完成后恢复活跃状态
        entity.setStatus(LifeEntityStatus.ACTIVE);
        
        LifeEntity savedEntity = lifeEntityRepository.save(entity);
        
        // 广播状态变更事件
        webSocketController.broadcastStatusChanged(savedEntity, oldStatus, LifeEntityStatus.ACTIVE.name());
        
        return savedEntity;
    }

    /**
     * 获取生命体统计信息
     */
    public Map<String, Object> getStatistics() {
        log.debug("Getting life entity statistics");
        
        // 总数统计
        long totalCount = lifeEntityRepository.count();
        
        // 按类型统计
        List<Object[]> typeStats = lifeEntityRepository.countByType();
        Map<String, Long> typeCountMap = typeStats.stream()
            .collect(Collectors.toMap(
                arr -> arr[0].toString(),
                arr -> (Long) arr[1]
            ));
        
        // 按状态统计
        List<Object[]> statusStats = lifeEntityRepository.countByStatus();
        Map<String, Long> statusCountMap = statusStats.stream()
            .collect(Collectors.toMap(
                arr -> arr[0].toString(),
                arr -> (Long) arr[1]
            ));
        
        // 按意识水平统计
        List<Object[]> consciousnessStats = lifeEntityRepository.countByConsciousnessLevel();
        Map<String, Long> consciousnessCountMap = consciousnessStats.stream()
            .collect(Collectors.toMap(
                arr -> arr[0].toString(),
                arr -> (Long) arr[1]
            ));
        
        // 平均值统计
        Double averageAge = lifeEntityRepository.getAverageAgeInDays();
        BigDecimal averageWisdom = lifeEntityRepository.getAverageWisdomScore();
        BigDecimal averageCreativity = lifeEntityRepository.getAverageCreativityScore();
        BigDecimal averageCollaboration = lifeEntityRepository.getAverageCollaborationScore();
        
        return Map.of(
            "totalCount", totalCount,
            "typeStats", typeCountMap,
            "statusStats", statusCountMap,
            "consciousnessStats", consciousnessCountMap,
            "averageAge", averageAge != null ? averageAge : 0.0,
            "averageWisdom", averageWisdom != null ? averageWisdom : BigDecimal.ZERO,
            "averageCreativity", averageCreativity != null ? averageCreativity : BigDecimal.ZERO,
            "averageCollaboration", averageCollaboration != null ? averageCollaboration : BigDecimal.ZERO
        );
    }

    /**
     * 获取活跃的生命体列表
     */
    public List<LifeEntity> findActiveEntities() {
        List<LifeEntityStatus> activeStatuses = List.of(
            LifeEntityStatus.ACTIVE,
            LifeEntityStatus.EVOLVING
        );
        return lifeEntityRepository.findActiveEntities(activeStatuses);
    }

    /**
     * 获取需要关注的生命体（健康度或能量低）
     */
    public List<LifeEntity> findEntitiesNeedingAttention() {
        BigDecimal healthThreshold = BigDecimal.valueOf(30.0);
        BigDecimal energyThreshold = BigDecimal.valueOf(20.0);
        return lifeEntityRepository.findEntitiesNeedingAttention(healthThreshold, energyThreshold);
    }

    /**
     * 获取最近活跃的生命体
     */
    public List<LifeEntity> findRecentlyActive(int hours) {
        LocalDateTime since = LocalDateTime.now().minusHours(hours);
        return lifeEntityRepository.findRecentlyActive(since);
    }

    /**
     * 批量更新生命体状态
     */
    @Transactional
    public void batchUpdateStatus(List<Long> ids, LifeEntityStatus status) {
        log.info("Batch updating {} life entities to status: {}", ids.size(), status);
        
        List<LifeEntity> entities = lifeEntityRepository.findAllById(ids);
        entities.forEach(entity -> {
            if (!entity.getDeleted()) {
                entity.setStatus(status);
                entity.updateLastActiveTime();
            }
        });
        
        lifeEntityRepository.saveAll(entities);
        log.info("Batch update completed for {} entities", entities.size());
    }
}